修正了充值页“原价 / 实付 / 折扣 / 充值分组倍率”相关的展示不一致问题#4644
修正了充值页“原价 / 实付 / 折扣 / 充值分组倍率”相关的展示不一致问题#4644laiyonghao wants to merge 5 commits intoQuantumNous:mainfrom
Conversation
|
ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (3)
WalkthroughThe PR exposes a backend-computed topup_group_ratio, parses and stores discounts safely on the frontend, extends preset pricing to include the group ratio and USD rate, and updates classic and default UIs to render original price, payable amount, discounts, and a preset synchronization lock. ChangesGroup-Based Top-Up Discount Aggregation
Sequence DiagramsequenceDiagram
participant Client as Client/Frontend
participant Controller as Backend Controller
participant UserGroup as User Group Service
participant PricingCalc as Pricing Calculator
participant UI as UI Renderer
Client->>Controller: GetTopUpInfo(userId)
Controller->>UserGroup: LoadUserGroup(userId)
UserGroup-->>Controller: Group Info
Controller->>Controller: Compute topupGroupRatio
Controller-->>Client: TopupInfo {topup_group_ratio, discount, ...}
Client->>PricingCalc: SelectPreset(presetValue)
Note over Client: Parse discounts<br/>Extract topup_group_ratio
Client->>PricingCalc: CalculatePresetPricing(presetValue, priceRatio, discount, topupGroupRatio)
PricingCalc->>PricingCalc: originalPrice = presetValue × priceRatio × topupGroupRatio
PricingCalc->>PricingCalc: actualPrice = originalPrice × discount
PricingCalc-->>Client: {originalPrice, actualPrice, displayValue}
Client->>UI: Render Preset Card
Note over UI: Show original price,<br/>actual payable amount,<br/>savings/discount
UI-->>Client: Updated UI with pricing
Estimated Code Review Effort🎯 3 (Moderate) | ⏱️ ~35 minutes Possibly Related PRs
Suggested Reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
本 PR 旨在对齐 classic 与 default 两套前端在充值页中“原价 / 实付 / 折扣 / 充值分组倍率”的展示与计算口径,并由后端明确下发当前用户生效的充值分组倍率,从而减少前端自行推断导致的不一致。
Changes:
- 后端
/api/user/topup/info补充返回当前用户的topup_group_ratio,用于前端展示与计算对齐。 - default 前端:预设卡与输入框说明补充“原价/实付”展示,并在预设金额定价计算中纳入分组倍率。
- classic 前端:解析折扣映射、展示原价/实付,并通过锁避免选择预设后首次手动修改不刷新的问题。
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| controller/topup.go | 在充值信息接口中返回当前用户生效的充值分组倍率 topup_group_ratio |
| web/default/src/features/wallet/types.ts | 为 TopupInfo 增加 topup_group_ratio 字段类型定义 |
| web/default/src/features/wallet/lib/format.ts | 预设金额定价计算纳入 topupGroupRatio |
| web/default/src/features/wallet/components/recharge-form-card.tsx | 预设卡与输入框下方金额说明增加“原价/实付”展示,并纳入分组倍率 |
| web/classic/src/components/topup/RechargeCard.jsx | classic 充值页展示原价/实付、修复预设后首次手动修改不刷新的同步问题,并对齐倍率/折扣口径 |
| web/classic/src/components/topup/index.jsx | 解析并规范化折扣映射,存储并使用后端下发的 topup_group_ratio,选择预设时按新口径计算 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| topupInfo?.discount?.[preset.value] ?? | ||
| topupInfo?.discount?.[String(preset.value)] ?? | ||
| preset.discount |
There was a problem hiding this comment.
🧹 Nitpick comments (3)
controller/topup.go (1)
26-32: ⚡ Quick winGraceful fallback recommended for
GetUserGroupfailures.
GetTopUpInfois purely informational — it powers the topup page. Ifmodel.GetUserGroupreturns an error (e.g., transient DB hiccup, stale session, or Redis<->DB inconsistency), the entire topup page now fails to load instead of falling back to a sane default, which is a UX regression compared to the pre-PR behavior where this lookup wasn't required at all.Since
common.GetTopupGroupRatioalready returns1for unknown groups andgetPayMoneydefensively resets0ratios to1, mirroring that defensiveness here keeps the page functional and only loses the (cosmetic) per-user discount preview.♻️ Proposed graceful fallback
func GetTopUpInfo(c *gin.Context) { id := c.GetInt("id") - group, err := model.GetUserGroup(id, true) - if err != nil { - common.ApiError(c, err) - return - } - topupGroupRatio := common.GetTopupGroupRatio(group) + topupGroupRatio := 1.0 + if group, err := model.GetUserGroup(id, true); err == nil { + if r := common.GetTopupGroupRatio(group); r > 0 { + topupGroupRatio = r + } + } else { + common.SysLog(fmt.Sprintf("GetTopUpInfo: failed to load user group for id=%d, falling back to ratio=1: %s", id, err.Error())) + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controller/topup.go` around lines 26 - 32, GetUserGroup errors should not abort GetTopUpInfo; instead fall back to a nil/unknown group so the page still renders. Replace the current error branch in controller/topup.go (the call to model.GetUserGroup and the ApiError return) with logic that on error logs the failure (or ignores it) and sets group to a nil/unknown value so you can still call common.GetTopupGroupRatio(group) to obtain the safe default (common.GetTopupGroupRatio already returns 1 for unknown groups). Keep the function names model.GetUserGroup and common.GetTopupGroupRatio to locate the change.web/classic/src/components/topup/index.jsx (1)
720-723: 💤 Low valueInconsistent fallback for missing discounts (
||vs??).Line 722 uses
parsedDiscounts[amount] || 1.0while the newselectPresetAmount(lines 896-902) uses??with aNumber.isFiniteguard. WithparseDiscountMapguaranteeing values are finite numbers, both paths agree onundefined → 1.0, but they disagree on0(treated as "missing → 1.0" by||and "valid 0% price" by??). The same||is reused on line 951 fordiscountRate. While a discount of0is unusual, the divergence is a code smell that will eventually bite if such a config is introduced.♻️ Proposed alignment
- discount: parsedDiscounts[amount] || 1.0, + discount: Number.isFinite(parsedDiscounts[amount]) + ? parsedDiscounts[amount] + : 1.0,And similarly for the
discountRateprop on line 951.Also applies to: 891-907
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/classic/src/components/topup/index.jsx` around lines 720 - 723, Replace the loose-fallback (||) with the same finite-number guard used in selectPresetAmount so zero discounts are preserved: where customPresets builds discount using parsedDiscounts[amount] and where discountRate is derived, change the logic to use Number.isFinite(parsedDiscounts[amount]) ? parsedDiscounts[amount] : 1.0 (mirroring selectPresetAmount and parseDiscountMap assumptions) so undefined maps to 1.0 but 0 remains a valid discount.web/classic/src/components/topup/RechargeCard.jsx (1)
440-491: ⚡ Quick winHoist
topupGroupRatioandtopupRateto avoid recomputation per preset.
topupGroupRatiois already computed at component scope on line 135 ascurrentTopupGroupRatio, and thetopupRatecalculation appears identically at lines 440-444 (currency-rate display) and 487-491 (inside the preset.map). Recomputing them on every preset render is harmless but adds visual noise and risks the two definitions drifting apart in future edits — for example, if someone tightens the validation in one place but not the other, presets and the rate display could disagree.♻️ Proposed refactor
const currentTopupGroupRatio = Number(topupInfo?.topup_group_ratio) || 1; + const safeTopupRate = + Number.isFinite(Number(priceRatio)) && Number(priceRatio) > 0 + ? Number(priceRatio) + : 1; const currentOriginalAmount = - Number(topUpCount || 0) * Number(priceRatio || 0) * currentTopupGroupRatio; + Number(topUpCount || 0) * safeTopupRate * currentTopupGroupRatio;Then in the rate-display IIFE and inside the preset
.map, replace the inlinetopupRate/topupGroupRatiodefinitions with the hoistedsafeTopupRate/currentTopupGroupRatiovalues.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@web/classic/src/components/topup/RechargeCard.jsx` around lines 440 - 491, Hoist the repeated computations for topupGroupRatio and topupRate so presets and the rate display use a single source of truth: remove the duplicated local definitions inside the IIFE rate-display and inside the presetAmounts.map callback and reference the component-scoped currentTopupGroupRatio and a hoisted safeTopupRate (compute once using getCurrencyConfig()/priceRatio validation logic) instead; update places that currently declare topupGroupRatio and topupRate to use currentTopupGroupRatio and safeTopupRate (or rename consistently) so the rate display and per-preset calculations (in the presetAmounts.map) share the same validated values.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@controller/topup.go`:
- Around line 26-32: GetUserGroup errors should not abort GetTopUpInfo; instead
fall back to a nil/unknown group so the page still renders. Replace the current
error branch in controller/topup.go (the call to model.GetUserGroup and the
ApiError return) with logic that on error logs the failure (or ignores it) and
sets group to a nil/unknown value so you can still call
common.GetTopupGroupRatio(group) to obtain the safe default
(common.GetTopupGroupRatio already returns 1 for unknown groups). Keep the
function names model.GetUserGroup and common.GetTopupGroupRatio to locate the
change.
In `@web/classic/src/components/topup/index.jsx`:
- Around line 720-723: Replace the loose-fallback (||) with the same
finite-number guard used in selectPresetAmount so zero discounts are preserved:
where customPresets builds discount using parsedDiscounts[amount] and where
discountRate is derived, change the logic to use
Number.isFinite(parsedDiscounts[amount]) ? parsedDiscounts[amount] : 1.0
(mirroring selectPresetAmount and parseDiscountMap assumptions) so undefined
maps to 1.0 but 0 remains a valid discount.
In `@web/classic/src/components/topup/RechargeCard.jsx`:
- Around line 440-491: Hoist the repeated computations for topupGroupRatio and
topupRate so presets and the rate display use a single source of truth: remove
the duplicated local definitions inside the IIFE rate-display and inside the
presetAmounts.map callback and reference the component-scoped
currentTopupGroupRatio and a hoisted safeTopupRate (compute once using
getCurrencyConfig()/priceRatio validation logic) instead; update places that
currently declare topupGroupRatio and topupRate to use currentTopupGroupRatio
and safeTopupRate (or rename consistently) so the rate display and per-preset
calculations (in the presetAmounts.map) share the same validated values.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 49067ab2-6480-4f53-afcb-11a64edb388d
📒 Files selected for processing (6)
controller/topup.goweb/classic/src/components/topup/RechargeCard.jsxweb/classic/src/components/topup/index.jsxweb/default/src/features/wallet/components/recharge-form-card.tsxweb/default/src/features/wallet/lib/format.tsweb/default/src/features/wallet/types.ts
把充值页在 classic 和 default 两套前端里的显示和计算逻辑对齐,重点修正了“原价 / 实付 / 折扣 / 充值分组倍率”相关的展示不一致问题。改动范围只涉及充值相关逻辑,没有夹带无关修改。
📝 变更描述 / Description
这次修改主要做了三件事:
现在无论是预设卡、输入框下方金额说明,还是支付确认弹窗,原价和实付金额都按同一套规则计算:
充值数量 × 充值价格 × 充值分组倍率,再叠加充值金额折扣。
🚀 变更类型 / Type of change
🔗 关联任务 / Related Issue
✅ 提交前检查项 / Checklist
Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。📸 运行证明 / Proof of Work
本地已完成以下验证:
go test ./controller/...通过web/classic下bun run build通过web/default下bun run build通过Summary by CodeRabbit
New Features
Bug Fixes
Refactor